package cate.game.common.rpc;

import cp.solution.rpc.RpcMsgHead;
import cp.solution.rpc.listener.RpcFireAndForgetListener;
import cp.solution.rpc.listener.RpcRequestResponseListener;
import cp.solution.rpc.message.RpcMessage;

import java.util.function.BiConsumer;
import java.util.function.BiFunction;

public abstract class RpcListenerTemplate {

    public abstract void dispatchFireAndForget(RpcMsgHead head, byte[] msgBody);

    public abstract byte[] dispatchRequestResponse(RpcMsgHead head, byte[] msgBody);

    public abstract void onFireAndForget(String path, RpcFireAndForgetListener handler, int priority);

    public abstract void onRequestResponse(String path, RpcRequestResponseListener handler);


    public <T> void onFireAndForgetTemplate(String path, Class<T> inputClz, BiConsumer<RpcMsgHead, T> handler) {
        onFireAndForgetTemplate(path, inputClz, handler, 0);
    }

    public <T> void onFireAndForgetTemplate(String path, Class<T> inputClz, BiConsumer<RpcMsgHead, T> handler, int priority) {
        this.onFireAndForget(path, (head, bytes) -> {
            T input = RpcMessage.convertInputBytes(path, inputClz, bytes);
            handler.accept(head, input);
        }, priority);
    }


    public <T> void onRequestResponseTemplate(String path, Class<T> inputClz, BiFunction<RpcMsgHead, T, Object> handler) {
        this.onRequestResponse(path, (head, bytes) -> {
            T input = RpcMessage.convertInputBytes(path, inputClz, bytes);
            Object respObj = handler.apply(head, input);
            return RpcMessage.build(path, respObj);
        });
    }
}
